package com.songshan.filter;

import cn.hutool.core.text.AntPathMatcher;
import com.alibaba.fastjson.JSONObject;
import com.songshan.bean.User;

import com.songshan.dto.Result;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author feb
 * @date 2024/6/18
 * @Description: 是否登录判断过滤器
 */
public class LoginFilter implements Filter {

  private String[] filterPatterns;

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    //静态资源和用户登录请求不做处理
    if (matcher(request)) {
      chain.doFilter(request, response);
      return;
    }
    //从request中获取token，并解析携带的用户信息
    User user = getAuthentication(request);
    //没有登录，或者token过期
    if (user == null) {
      loginFail(request, response);
      return;
    }
    try {
      //将用户信息保存到线程共享对象
      UserContext.set(user);
      //将新的token返回给前端
      response.setHeader("token", user.getToken());
      //业务处理
      chain.doFilter(request, response);
    } finally {
      //业务处理完成后，清理当前线程的用户信息
      UserContext.remove();
    }
  }

  private void loginFail(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    String uri = request.getRequestURI();
    if (uri.endsWith(".htmlx")) {
      response.sendRedirect("/springmvc-demo/login.htmlx");
    } else {
      Result result = new Result();
      result.setCode(403);
      result.setMsg("登录过期！");
      response.setCharacterEncoding("utf-8");
      response.setContentType("application/json");
      PrintWriter out = response.getWriter();
      out.println(JSONObject.toJSONString(result));
      out.flush();
      out.close();
    }
  }

  private boolean matcher(HttpServletRequest request) {
    String uri = request.getRequestURI();
    AntPathMatcher matcher = new AntPathMatcher();
    for (String filterPattern : filterPatterns) {
      if (matcher.match(filterPattern, uri)) {
        return true;
      }
    }
    return false;
  }

  private User getAuthentication(HttpServletRequest request) {
    String token = request.getHeader("token");
    if (token == null || token.isEmpty()) {
      token = request.getParameter("token");
    }
    if (token == null || token.isEmpty()) {
      Cookie[] cookies = request.getCookies();
      if (cookies != null && cookies.length > 0) {
        for (Cookie cookie : cookies) {
          if (cookie.getName().equals("token")) {
            token = cookie.getValue();
          }
        }
      }
    }
    if (token != null && !token.isEmpty()) {
      boolean refresh =
          request.getHeader("refreshToken") != null && request.getHeader("refreshToken")
              .equals("true");
      User user = JWTUtil.parseToken(token, refresh);
      if (user != null) {
        return user;
      }
    }
    return null;
  }

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    String filterPatternsVal = filterConfig.getInitParameter("filterPatterns");
    if (filterPatternsVal != null && !filterPatternsVal.isEmpty()) {
      this.filterPatterns = filterPatternsVal.split(";");
    } else {
      this.filterPatterns = new String[]{};
    }
  }

  @Override
  public void destroy() {

  }
}
